﻿@implements IDisposable

@using BlazorFinancePortfolio.Models
@using BlazorFinancePortfolio.Helpers
@using BlazorPro.BlazorSize

@inject ResizeListener listener

@if (MainChartType == ChartSeriesType.Candlestick)
{
    <TelerikStockChart @ref="@StockChartRef" DateField="@nameof(StockIntervalDetails.Date)">

        <StockChartNavigator>
            <StockChartNavigatorSeriesItems>
                <StockChartNavigatorSeries Type="StockChartSeriesType.Area"
                                           Field="@( nameof(StockIntervalDetails.Volume) )"
                                           Color="@GetSeriesColor(ChartSeriesType.Area)"
                                           Data="@ChartData">
                </StockChartNavigatorSeries>
            </StockChartNavigatorSeriesItems>

            <StockChartNavigatorCategoryAxis Type="@ChartCategoryAxisType.Date"
                                    BaseUnit="@IntervalFilter.Interval.Unit"
                                    BaseUnitStep="@IntervalFilter.Interval.Step">
                <StockChartNavigatorCategoryAxisLabels>
                </StockChartNavigatorCategoryAxisLabels>
            </StockChartNavigatorCategoryAxis>

            <StockChartNavigatorSelect From="@GetNavigatorStart()" To="@GetNavigatorEnd()">
                <StockChartNavigatorSelectMousewheel Zoom="@ChartMousewheelZoom.Both" Reverse="true" />
            </StockChartNavigatorSelect>
            <StockChartNavigatorHint Visible="true" Format="{0:d} - {1:d}" />

        </StockChartNavigator>

        <StockChartSeriesItems>
            <StockChartSeries Type="@StockChartSeriesType.Candlestick" Data="@ChartData"
                              OpenField="@( nameof(StockIntervalDetails.Open) )"
                              CloseField="@( nameof(StockIntervalDetails.Close) )"
                              HighField="@( nameof(StockIntervalDetails.High) )"
                              LowField="@( nameof(StockIntervalDetails.Low) )"
                              DownColor="#FF6358"
                              Color="@GetSeriesColor(MainChartType)">
            </StockChartSeries>
            <StockChartSeries Type="@StockChartSeriesType.Column" Data="@ChartData"
                              Field="@( nameof(StockIntervalDetails.Volume) )"
                              CategoryField="@( nameof(StockIntervalDetails.Date) )"
                              ColorField="@( nameof(StockIntervalDetails.ColumnColor) )"
                              Aggregate="@ChartSeriesAggregate.Sum"
                              Gap="0.75"
                              Axis="Volume">
                <StockChartSeriesTooltip>
                   <Template>@( SelectedCurrency.Sign + (context.DataItem as StockIntervalDetails).Volume.ToString("N3") )</Template>
                </StockChartSeriesTooltip>
            </StockChartSeries>
        </StockChartSeriesItems>

        <StockChartCategoryAxes>
            <StockChartCategoryAxis Type="@ChartCategoryAxisType.Date">
                <StockChartCategoryAxisCrosshair Visible="true">
                    <StockChartCategoryAxisCrosshairTooltip Visible="true" />
                </StockChartCategoryAxisCrosshair>
                <StockChartCategoryAxisLabels>
                    <StockChartCategoryAxisLabels Step="@LabelStep"></StockChartCategoryAxisLabels>
                </StockChartCategoryAxisLabels>
                <StockChartCategoryAxisMajorGridLines Visible="true" />
                <StockChartCategoryAxisMinorGridLines Visible="false" />
            </StockChartCategoryAxis>
        </StockChartCategoryAxes>

        <StockChartValueAxes>
            <StockChartValueAxis>
                <StockChartValueAxisCrosshair Visible="true">
                    <StockChartValueAxisCrosshairTooltip Visible="true" />
                </StockChartValueAxisCrosshair>
                @*<StockChartValueAxisLabels Format="@( SelectedCurrency.Sign + "{0}" )"  />*@
                <StockChartValueAxisMinorGridLines Visible="false" />
            </StockChartValueAxis>
            <StockChartValueAxis Name="Volume" Min="0" Max="@VolumeValueAxisMax()" Visible="false"></StockChartValueAxis>
        </StockChartValueAxes>

        <StockChartLegend Visible="false" />
        <StockChartTooltip Visible="true" />

    </TelerikStockChart>
}
else
{
    <TelerikChart @ref="@ChartRef">
        <ChartSeriesItems>
            <ChartSeries Type="@MainChartType" Data="@ChartData"
                         Field="@( nameof(StockIntervalDetails.Close) )"
                         CategoryField="@( nameof(StockIntervalDetails.Date) )"
                         Style="@ChartSeriesStyle.Smooth"
                         Color="@( MainChartType == ChartSeriesType.Line ? "#2D73F5" : "#007BFF" )">
                <ChartSeriesLine Style="@ChartSeriesLineStyle.Smooth" />
            </ChartSeries>
            @if (MainChartType == ChartSeriesType.Line)
            {
                <ChartSeries Type="@ChartSeriesType.Column" Data="@ChartData"
                             Field="@( nameof(StockIntervalDetails.Volume) )"
                             CategoryField="@( nameof(StockIntervalDetails.Date) )"
                             ColorField="@( nameof(StockIntervalDetails.ColumnColor) )"
                             Aggregate="@ChartSeriesAggregate.Sum"
                             Gap="0.75"
                             Axis="Volume">
                    <ChartSeriesTooltip>
                        <Template>@( SelectedCurrency.Sign + (context.DataItem as StockIntervalDetails).Volume.ToString("N3") )</Template>
                    </ChartSeriesTooltip>
                </ChartSeries>
            }
        </ChartSeriesItems>
        <ChartCategoryAxes>
            <ChartCategoryAxis Type="@ChartCategoryAxisType.Date"
                               BaseUnit="@IntervalFilter.Interval.Unit"
                               BaseUnitStep="@IntervalFilter.Interval.Step"
                               MaxDateGroups="20">
                <ChartCategoryAxisLabels Format="dd/yyyy">
                    <ChartCategoryAxisLabels Step="@LabelStep"></ChartCategoryAxisLabels>
                </ChartCategoryAxisLabels>
                <ChartCategoryAxisMajorGridLines Visible="true" />
                <ChartCategoryAxisMinorGridLines Visible="false" />
            </ChartCategoryAxis>
        </ChartCategoryAxes>
        <ChartValueAxes>
            <ChartValueAxis>
                <ChartValueAxisLabels Format="@( SelectedCurrency.Sign + "{0}" )" />
                <ChartValueAxisMinorGridLines Visible="false" />
            </ChartValueAxis>
            <ChartValueAxis Name="Volume" Min="0" Max="@VolumeValueAxisMax()" Visible="false"></ChartValueAxis>
        </ChartValueAxes>
        <ChartLegend Visible="false" />
        <ChartTooltip Visible="true" />
    </TelerikChart>
}
@code{
    [Parameter] public ChartSeriesType MainChartType { get; set; }
    [Parameter] public List<StockIntervalDetails> ChartData { get; set; }
    [Parameter] public int LabelStep { get; set; }
    [Parameter] public IntervalFilter IntervalFilter { get; set; }

    [CascadingParameter] public Currency SelectedCurrency { get; set; }
    TelerikChart ChartRef { get; set; }
    TelerikStockChart StockChartRef { get; set; }
    int LastViewPortWidth { get; set; }
    long VolumeValueAxisMax()
    {
        if (ChartData == null || ChartData.Count == 0)
        {
            return 100;
        }
        return (long)Math.Round(ChartData.Max(d => d.Volume) * 6);
    }

    protected override async Task OnParametersSetAsync()
    {
        if (IntervalFilter == null)
        {
            IntervalFilter = GetDefaultFilter();
        }
        await AdjustLabelStep(null);
        await base.OnParametersSetAsync();
    }

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            listener.OnResized += ResizeChart;
        }
    }

    async void ResizeChart(object _, BrowserWindowSize window)
    {
        if (LastViewPortWidth != window.Width)
        {
            LastViewPortWidth = window.Width;
            await AdjustLabelStep(window.Width);
            ChartRef?.Refresh();
            StockChartRef?.Refresh();
        }
    }

    async Task AdjustLabelStep(int? WindowWidth)
    {
        if (ChartData.Any())
        {
            var chartDataTimeRangeInMs = (long)(ChartData.Last().Date - ChartData.First().Date).TotalMilliseconds;
            int currStep = (int)(chartDataTimeRangeInMs / IntervalFilter.Duration / Constants.MaxLabelStepsInStocksChart);
            if (WindowWidth == null)
            {
                BrowserWindowSize size = await listener.GetBrowserWindowSize();
                WindowWidth = size.Width;
                LastViewPortWidth = WindowWidth.Value;
            }
            if (WindowWidth < 768)
            {
                currStep = currStep * 5;
            }
            LabelStep = currStep;
            StateHasChanged();
        }
    }

    public void Dispose()
    {
        listener.OnResized -= ResizeChart;
    }

    IntervalFilter GetDefaultFilter()
    {
        return new IntervalFilter()
        {
            Duration = Constants.MS_1_HOUR,
            Interval = new Interval { Step = 60, Unit = ChartCategoryAxisBaseUnit.Minutes }
        };
    }

    string GetSeriesColor(ChartSeriesType chartType)
    {
        switch (chartType)
        {
            case ChartSeriesType.Candlestick:
                return "#5CB85C";
            case ChartSeriesType.Area:
            case ChartSeriesType.Line:
                return "#007BFF";
            default:
                break;
        }
        return "#007BFF";
    }

    DateTime GetNavigatorStart()
    {
        if (ChartData.Any())
        {
            int initialIndex = Convert.ToInt32(ChartData.Count * 0.15);
            return ChartData[initialIndex].Date;
        }
        return DateTime.MinValue;
    }

    DateTime GetNavigatorEnd()
    {
        if (ChartData.Any())
        {
            int initialIndex = Convert.ToInt32(ChartData.Count * 0.4);
            return ChartData[initialIndex].Date;
        }
        return DateTime.MaxValue;
    }
}